package com.tian.arch.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding
import com.tian.arch.Foundation
import com.tian.arch.util.observe


abstract class BaseFragment<VM : BaseViewModel, VB : ViewBinding>(private val inflate: (LayoutInflater, ViewGroup?, Boolean) -> VB) :
    Fragment(), IView {

    protected abstract val vm: VM

    private var _vb: VB? = null
    protected val vb: VB get() = _vb!!

    override val displayDelegate by lazy { Foundation.globalConfig().displayDelegate.invoke() }
    override val disposableManager by lazy { DisposeManager() }

    private var subscribedLoading = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        onBackPressed()?.let {
            requireActivity().onBackPressedDispatcher.addCallback(object :
                OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                    it.invoke()
                }
            })
        }
    }

    /**
     * 处理回退事件
     */
    open fun onBackPressed(): (() -> Unit)? {
        return null
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        disposableManager.init(this)
        val root = inflateView(inflater, container)
        displayDelegate.init(requireActivity())
        subscribeLoading()
        return root
    }

    protected open fun inflateView(inflater: LayoutInflater, container: ViewGroup?): View {
        _vb = inflate(inflater, container, false)
        return vb.root
    }

    open fun subscribeLiveData() {
        subscribeLoading()
    }

    private fun subscribeLoading() {
        if (subscribedLoading) return
        observe(vm.loading) {
            when (it) {
                is LoadingState.Loading -> displayDelegate.showLoadingDialog(it.message)
                is LoadingState.Hide -> displayDelegate.dismissLoadingDialog()
            }
        }
        subscribedLoading = true
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _vb = null
    }

}